package com.eco.fanliapp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eco.fanliapp.common.constant.NewsEnumLog;
import com.eco.fanliapp.common.constant.WechatConfig;
import com.eco.fanliapp.common.response.ServerResponse;
import com.eco.fanliapp.dao.SyChannelMapper;
import com.eco.fanliapp.dao.SyChannelUserMapper;
import com.eco.fanliapp.entity.AppUser;
import com.eco.fanliapp.entity.SyChannel;
import com.eco.fanliapp.entity.SyChannelUser;
import com.eco.fanliapp.service.*;
import com.eco.fanliapp.utils.DateFormatUtils;
import com.eco.fanliapp.utils.EasyPoiStyleUtils;
import com.eco.fanliapp.utils.EasyPoiUtils;
import com.eco.fanliapp.utils.StringUtils;
import com.eco.fanliapp.vo.SyChannelGroupVo;
import com.eco.fanliapp.vo.SyChannelUserVO;
import com.eco.fanliapp.vo.SyChannelVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 渠道表 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2019-08-21
 */
@Service
public class SyChannelServiceImpl extends ServiceImpl<SyChannelMapper, SyChannel> implements ISyChannelService {

    @Autowired
    private ISyChannelService syChannelService;

    @Autowired
    private SyChannelUserMapper syChannelUserMapper;

    @Autowired
    private SyChannelMapper syChannelMapper;

    @Autowired
    private RedisTemplateService redisTemplateService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IAppUserOrderService appUserOrderService;
    @Autowired
    private IAppUserService appUserService;
    @Autowired
    private IDwzService dwzService;
    @Autowired
    private ISyChannelUserService syChannelUserService;
    /**
     * 根据渠道邀请码获取渠道
     *
     * @param channelInviteCode
     * @param type              1优先从redis获取0从数据库中获取
     * @return
     */
    @Override
    public SyChannel findSyChannelUserById(String channelInviteCode, int type) {
        //根据渠道邀请码获取渠道信息
        SyChannel syChannel = null;
        String redisKeyStr = "app_channel_company_" + channelInviteCode;
        if (type == 1 && redisTemplateService.hasKey(redisKeyStr)) {
            syChannel = redisTemplateService.getTByKey(redisKeyStr, SyChannel.class);
        }
        if (syChannel == null) {
            //查询渠道信息
            QueryWrapper<SyChannel> query = new QueryWrapper<>();
            query.eq("channel_invite_code", channelInviteCode);
            query.eq("enable", true);
            query.eq("deleted", false);
            List<SyChannel> list = syChannelService.list(query);
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(list)) {
                syChannel = list.get(0);
                redisTemplateService.set(redisKeyStr, syChannel, 60 * 5);
            }
        }
        return syChannel;
    }

    /**
     * 生成渠道短链
     *
     * @param inviteCode 渠道邀请码
     * @return
     */
    @Override
    public String linkCreate(String inviteCode, Integer companyId) {
        try {

            //type=5  邀请赚钱
            //type=0   渠道分享
            //type=1  详情分享
            String str = "type=0&jumpType=1&linkType=0" + "&channelCode=" + inviteCode;
            String data = "shengya!!!" + str + "shengya!!!";
            String longUrl = null;
            if (companyId != null) {
                if (companyId == 42 || companyId == 43) {
                    longUrl = WechatConfig.RED_MONEY_COMMUNITY_URL + "?type=0&jumpType=1&linkType=0" + "&channelCode=" + inviteCode + "&str=" + URLEncoder.encode(data, "UTF-8");
                } else {
                    longUrl = WechatConfig.RED_MONEY_URL + "?type=0&jumpType=1&linkType=0" + "&channelCode=" + inviteCode + "&str=" + URLEncoder.encode(data, "UTF-8");
                }
            } else {
                longUrl = WechatConfig.RED_MONEY_URL + "?type=0&jumpType=1&linkType=0" + "&channelCode=" + inviteCode + "&str=" + URLEncoder.encode(data, "UTF-8");
            }
            //拼接url路径
//            String longUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WechatConfig.APPID + "&redirect_uri=" + WechatConfig.RETURNURL
//                    + "&response_type=code&scope=snsapi_userinfo&state=channelCode:" + inviteCode + "#wechat_redirect";
            //调用工具类生成短链
            String shorUrl = dwzService.getShorUrl(longUrl);
            return shorUrl;
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 生成渠道短链
     *
     * @param inviteCode 渠道邀请码
     * @return
     */
    @Override
    public String linkCreateNew(String inviteCode, Integer companyId) {
        try {

            //type=5  邀请赚钱
            //type=0   渠道分享
            //type=1  详情分享
            String redirectYuming1 = WechatConfig.RED_MONEY_SHARE_URL;

            String redisKeyStr1 = "app_wechatConfig_channel_start_url";
            if (redisTemplate.hasKey(redisKeyStr1)) {
                try {
                    redirectYuming1 = stringRedisTemplate.opsForValue().get(redisKeyStr1);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                stringRedisTemplate.opsForValue().set(redisKeyStr1, redirectYuming1);
            }

//            String longUrl = redirectYuming1 + "?channelCode=" + inviteCode + "&companyId=" + companyId;

            String longUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WechatConfig.APPID + "&redirect_uri=" + WechatConfig.RETURNURL + "&response_type=code&scope=snsapi_userinfo&state=channelCode:" + inviteCode + ":" + companyId + "#wechat_redirect";

            //拼接url路径
//            String longUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WechatConfig.APPID + "&redirect_uri=" + WechatConfig.RETURNURL
//                    + "&response_type=code&scope=snsapi_userinfo&state=channelCode:" + inviteCode + "#wechat_redirect";
            //调用工具类生成短链
            String shorUrl = dwzService.getShorUrl(longUrl);
            return shorUrl;
        } catch (Exception e) {
        }
        return null;
    }

    @Override
    public ServerResponse manageStatistical(int currentPage, int pageSize, Integer companyId, String searchDate, String keyWord) {
        String redisKey = "resultMap_" + companyId;
        //获取缓存内容
        Map<String, Object> resultMap1 = redisTemplate.opsForHash().entries(redisKey);
        if ((keyWord == null || "".equals(keyWord)) && (searchDate == null || "".equals(searchDate)) && resultMap1 != null && resultMap1.size() > 0) {
            return ServerResponse.createBySuccess("统计结果成功", resultMap1);
        }

        //分页
        //PageHelper.startPage(currentPage, pageSize);
        //统计总佣金；
        Map<String, Object> map = new HashMap<>();
        map.put("companyId", companyId);
        map.put("searchDate", searchDate);
        map.put("keyWord", keyWord);
        //统计每个渠道下佣金
        List<SyChannelUserVO> department = syChannelUserMapper.totalManageStatistical(map);

        BigDecimal baseMoney = new BigDecimal(0);//联盟佣金
        BigDecimal baseComm = new BigDecimal(0);//返利佣金
        Integer baseOrderNum = 0;//订单数
        Integer baseRegistNum = 0;//总注册量
        Integer baseOrderUser = 0;//总下单用户
        Integer baseYerRegist = 0;//昨日注册量
        Integer baseYerOrder = 0;//昨日下单用户
        for (SyChannelUserVO vo : department) {
            //设置日期
            vo.setCreateTime(searchDate);
            baseMoney = baseMoney.add(new BigDecimal(vo.getTotalMoney()));
            baseComm = baseComm.add(new BigDecimal(vo.getCommission()));
            baseOrderNum += vo.getOrderNum();
            baseRegistNum += vo.getTotalRegistNum();
            baseOrderUser += vo.getOrderTotalUser();
            baseYerRegist += vo.getYesterdayRegistNum();
            baseYerOrder += vo.getYesterdayOrderTotalUser();
        }
        //封装总的统计结果
        SyChannelUserVO newVo = new SyChannelUserVO();
        newVo.setCompanyName("总量统计");
        newVo.setChannelName("汇总");
        newVo.setTotalMoney(baseMoney.doubleValue());
        newVo.setCommission(baseComm.doubleValue());
        newVo.setOrderNum(baseOrderNum);
        newVo.setTotalRegistNum(baseRegistNum);
        newVo.setOrderTotalUser(baseOrderUser);
        newVo.setYesterdayRegistNum(baseYerRegist);
        newVo.setYesterdayOrderTotalUser(baseYerOrder);
        newVo.setCreateTime(searchDate);
        //返回前端list
        List<SyChannelUserVO> summary = new ArrayList<>();
        summary.add(newVo);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("summary", summary);//总的统计
        resultMap.put("department", department);//每个渠道统计
        //存入缓存中，设置有效期为1个小时
        redisTemplate.opsForHash().putAll(redisKey, resultMap);
        redisTemplate.expire(redisKey, 1, TimeUnit.HOURS); //设置超时时间1小时
        return ServerResponse.createBySuccess("统计结果成功", resultMap);
    }

    @Override
    public void exportManageStatistical(HttpServletResponse response, Integer companyId, String searchDate) {
        String redisKey = "resultMap_" + companyId;
        List<SyChannelUserVO> department = null;
        List<SyChannelUserVO> summary = new ArrayList<>();

        //获取缓存内容
        Map<String, Object> resultMap1 = redisTemplate.opsForHash().entries(redisKey);
        if ((searchDate == null || "".equals(searchDate)) && resultMap1 != null && resultMap1.size() > 0) {
            department = (List<SyChannelUserVO>) resultMap1.get("department");
            List<SyChannelUserVO> summary1 = (List<SyChannelUserVO>) resultMap1.get("summary");
            summary.addAll(summary1);
        } else {
            //统计总佣金；
            Map<String, Object> map = new HashMap<>();
            map.put("companyId", companyId);
            map.put("searchDate", searchDate);
            //统计每个渠道下佣金
            department = syChannelUserMapper.totalManageStatistical(map);

            BigDecimal baseMoney = new BigDecimal(0);//联盟佣金
            BigDecimal baseComm = new BigDecimal(0);//返利佣金
            Integer baseOrderNum = 0;//订单数
            Integer baseRegistNum = 0;//总注册量
            Integer baseOrderUser = 0;//总下单用户
            Integer baseYerRegist = 0;//昨日注册量
            Integer baseYerOrder = 0;//昨日下单用户
            for (SyChannelUserVO vo : department) {
                baseMoney = baseMoney.add(new BigDecimal(vo.getTotalMoney()));
                baseComm = baseComm.add(new BigDecimal(vo.getCommission()));
                baseOrderNum += vo.getOrderNum();
                baseRegistNum += vo.getTotalRegistNum();
                baseOrderUser += vo.getOrderTotalUser();
                baseYerRegist += vo.getYesterdayRegistNum();
                baseYerOrder += vo.getYesterdayOrderTotalUser();
                //设置日期
                vo.setCreateTime(searchDate);
            }
            //封装总的统计结果
            SyChannelUserVO newVo = new SyChannelUserVO();
            newVo.setCompanyName("总量统计");
            newVo.setChannelName("汇总");
            newVo.setTotalMoney(baseMoney.doubleValue());
            newVo.setCommission(baseComm.doubleValue());
            newVo.setOrderNum(baseOrderNum);
            newVo.setTotalRegistNum(baseRegistNum);
            newVo.setOrderTotalUser(baseOrderUser);
            newVo.setYesterdayRegistNum(baseYerRegist);
            newVo.setYesterdayOrderTotalUser(baseYerOrder);
            newVo.setCreateTime(searchDate);
            //返回前端list
            summary.add(newVo);
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("summary", summary);//总的统计
            resultMap.put("department", department);//每个渠道统计
            //存入缓存中，设置有效期为1个小时
            redisTemplate.opsForHash().putAll(redisKey, resultMap);
            redisTemplate.expire(redisKey, 1, TimeUnit.HOURS); //设置超时时间1小时
        }

        //导出excel
        List<SyChannelUserVO> excel = new ArrayList<>();
        excel.addAll(summary);
        excel.addAll(department);
        EasyPoiUtils.exportExcel(excel, "渠道关系统计", "渠道关系统计", SyChannelUserVO.class, EasyPoiStyleUtils.class, "渠道关系统计.xls", response);

    }

    @Override
    public ServerResponse statisticalDetail(int currentPage, int pageSize, Long channelId) {
        PageHelper.startPage(currentPage, pageSize);
        List<SyChannelUserVO> detailList = syChannelUserMapper.statisticalDetail(channelId);
        return ServerResponse.createBySuccess("统计完毕", new PageInfo(detailList));
    }

    @Override
    public void exporttatisticalDetail(HttpServletResponse response, Long channelId) {
        List<SyChannelUserVO> detailList = syChannelUserMapper.statisticalDetail(channelId);

        //导出excel
        EasyPoiUtils.exportExcel(detailList, "渠道详情统计", "渠道详情统计", SyChannelUserVO.class, EasyPoiStyleUtils.class, "渠道详情统计.xls", response);

    }

    @Override
    public SyChannel getByTableId(long tableId) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("table_id", tableId);
        return syChannelMapper.selectOne(qw);
    }

    @Override
    public SyChannel findSyChannelByUserId(Long userId) {
        return syChannelMapper.findSyChannelByUserId(userId);
    }

    @Override
    public List<SyChannelUserVO> manageStatisticalNew(Integer companyId, String searchDate) {
        boolean bool = true;
        //获取锁
        if (searchDate != null && !"".equals(searchDate)) {
            bool = false;
        }
        String redisKey = "manageStatisticalNew_" + DateFormatUtils.getNowDateDay(new Date()) + "_" + companyId;
        //今日缓存是否已存在；昨日缓存是否已删除
        if (redisTemplateService.hasKey(redisKey) && bool) {
            List<SyChannelUserVO> list = redisTemplateService.getTByListKey(redisKey, SyChannelUserVO.class);
            if (!CollectionUtils.isEmpty(list)) {
                return list;
            }
        }
        //结果集
        List<SyChannelUserVO> list = new ArrayList<>();
        //遍历渠道列表
        List<SyChannelVo> syChannels = syChannelMapper.syChannelList(companyId);
        for (SyChannelVo channel : syChannels) {
            SyChannelUserVO vo = new SyChannelUserVO();
            vo.setCompanyId(Long.valueOf(channel.getCompanyId()));
            vo.setCompanyName(channel.getCompayName());
            vo.setChannelId(channel.getTableId());
            vo.setChannelName(channel.getChannelName());
            //联盟佣金，返利佣金，订单数
            SyChannelUserVO voBase = appUserOrderService.selectOrderMessage(channel.getTableId(), searchDate);
            vo.setTotalMoney(voBase.getTotalMoney());
            vo.setCommission(voBase.getCommission());
            vo.setOrderNum(voBase.getOrderNum());
            //ps:说明 所有：flag = null；昨日：flag =1 ；非免单：freeFlag = null;免单：freeFlag =1
            //总注册量
            Integer users = appUserService.selectRegistUser(channel.getTableId(), null);
            vo.setTotalRegistNum(users);
            //当日注册量
            Integer yearsUsers = appUserService.selectRegistUser(channel.getTableId(), 1);
            vo.setYesterdayRegistNum(yearsUsers);
            //总下单用户
            Integer orders = appUserOrderService.selectOrderUser(channel.getTableId(), null, null);
            vo.setOrderTotalUser(orders);
            //当日下单用户
            Integer yearsOrders = appUserOrderService.selectOrderUser(channel.getTableId(), 1, null);
            vo.setYesterdayOrderTotalUser(yearsOrders);
            //总免单用户
            Integer freeUser = appUserOrderService.selectOrderUser(channel.getTableId(), null, 1);
            vo.setFreeUsers(freeUser);
            //当天免单用户
            Integer yearsFreeUser = appUserOrderService.selectOrderUser(channel.getTableId(), 1, 1);
            vo.setFreeUsersYestr(yearsFreeUser);

            //封装结果集
            list.add(vo);
        }
        //存储缓存
        if (bool) {
            redisTemplateService.set(redisKey, list, 24 * 3600);
        }

        //释放锁
        return list;
    }

    @Override
    public List<SyChannelUserVO> statisticalDetailNew(Long channelId) {
        //获取锁

        String redisKey = "statisticalDetailNew_" + DateFormatUtils.getNowDateDay(new Date()) + "_" + channelId;
        //今日缓存是否已存在；昨日缓存是否已删除
        if (redisTemplateService.hasKey(redisKey)) {
            List<SyChannelUserVO> list = redisTemplateService.getTByListKey(redisKey, SyChannelUserVO.class);
            if (!CollectionUtils.isEmpty(list)) {
                return list;
            }
        }
        //查询该渠道下所有时间的统计
        List<SyChannelUserVO> detailList = syChannelUserMapper.statisticalDetail(channelId);

        //存储缓存
        redisTemplateService.set(redisKey, detailList, 24 * 3600);//一天

        //释放锁
        return detailList;
    }

    @Override
    public void clearDate(Long channelId) {
        String redisKey = "statisticalDetailNew_" + DateFormatUtils.getNowDateDay(new Date()) + "_" + channelId;
        redisTemplateService.del(redisKey);
    }

    @Override
    public void handleDate(Integer companyId) {
        //获取所有没有渠道的用户
        List<AppUser> list = syChannelUserMapper.handleDate(companyId);
        //判断是否有上级
        for(AppUser user:list){
            if(StringUtils.isNotNull(user.getSuperInviteCode())){
                //根据上级来匹配渠道
                AppUser SJUser = appUserService.selectSuperUserInfoBySuperInviteCode(user.getSuperInviteCode());
                if (SJUser != null) {
                    //获取上级渠道信息
                    SyChannelUser channelUser = syChannelUserService.findSyChannelUserById(SJUser.getUserId(), 2);
                    if (channelUser != null) {
                        SyChannelUser syChannelUser = new SyChannelUser();
                        syChannelUser.setUserId(user.getUserId());
                        syChannelUser.setChannelId(channelUser.getChannelId());
                        syChannelUser.setChannelName(channelUser.getChannelName());
                        syChannelUser.setChannelInviteCode(channelUser.getChannelInviteCode());
                        if(user.getAppLogin() == 0){
                            syChannelUser.setChannelUserStatus(2);
                        }
                        syChannelUser.setCreateTime(new Date());
                        syChannelUserService.save(syChannelUser);
                    }
                }
            }
        }

        System.out.println(list.size());


    }

    @Override
    public void handleNotChannel(Integer companyId) {
        //=============未匹配用户匹配上=========
        Long channelId = 95L;
        String channelName = "自然渠道";
        String channelInviteCode = "wR9a3L";
        Date time = new Date();
        //指定公司对应指定渠道
        List<AppUser> list2  = syChannelUserMapper.handleNotChannel(companyId);
        if(!CollectionUtils.isEmpty(list2)){
            for(AppUser user2:list2){
                SyChannelUser syChannelUser = new SyChannelUser();
                syChannelUser.setUserId(user2.getUserId());
                syChannelUser.setChannelId(channelId);
                syChannelUser.setChannelName(channelName);
                syChannelUser.setChannelInviteCode(channelInviteCode);
                if(user2.getAppLogin() == 0){
                    syChannelUser.setChannelUserStatus(2);
                }
                syChannelUser.setCreateTime(time);
                syChannelUserService.save(syChannelUser);

            }
        }
    }

    @Override
    public List<Integer> findChannelListByGroupId(Integer groupId) {
        return syChannelMapper.findChannelListByGroupId(groupId);
    }

    @Override
    public List<SyChannelGroupVo> groupList(List<Integer> channelList, Long startTime, Long endTime) {
        //type = 1 转口令渠道 1，2，3，4
        //type = 2 活动如超级红包轮播渠道  6，7，10，11
        //type = 3 搜索框渠道  18，19
        //type = 4 淘礼金渠道  24
        //type = 5 社群后返渠道  26
        //type = 6 瀑布渠道  15

        List<SyChannelGroupVo> list = new ArrayList<>();
        for (int type = 1; type <= 6; type++) {
            //根据渠道id，类型，时间；筛选数据
            SyChannelGroupVo groupVo = syChannelMapper.groupList(channelList, type, startTime, endTime);
            //处理对象未空的情况
            SyChannelGroupVo groupVo1 = handlerGroupVo(groupVo, type);
            list.add(groupVo1);
        }

        return list;
    }


    /**
     * 处理渠道组数据为空的处理
     *
     * @param groupVo
     * @param type
     * @return
     */
    private SyChannelGroupVo handlerGroupVo(SyChannelGroupVo groupVo, int type) {
        if (groupVo == null) {
            groupVo = new SyChannelGroupVo();
            groupVo.setPubSharePreFee(new Double("0"));
            groupVo.setCommission(new Double("0"));
            groupVo.setOrderNum(0);
        }

        if (type == 1) {
            groupVo.setGroupName("转口令渠道");
        }
        if (type == 2) {
            groupVo.setGroupName("活动如超级红包轮播渠道");
        }
        if (type == 3) {
            groupVo.setGroupName("搜索框渠道");
        }
        if (type == 4) {
            groupVo.setGroupName("淘礼金渠道");
        }
        if (type == 5) {
            groupVo.setGroupName("社群后返渠道");
        }
        if (type == 6) {
            groupVo.setGroupName("瀑布渠道");
        }
        return groupVo;
    }

    @Override
    public List<SyChannelGroupVo> channelDetailList(Integer groupId, Long startTime, Long endTime, String channelName) {

        List<SyChannelGroupVo> list1 = syChannelMapper.channelDetailList(groupId, startTime, endTime, channelName);
        return list1;
    }


}
